home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 2004 #9
/
Amiga Plus CD - 2004 - No. 09.iso
/
amigaplus
/
tools
/
dev_libs
/
feelin040718
/
demos
/
lines.c
< prev
next >
Wrap
C/C++ Source or Header
|
2004-08-03
|
14KB
|
502 lines
;/*
SC Lines.c
QUIT
_________________________________________________________________________
Class2 Demo © 2000-2003 by Olivier LAVIALE <HaploLaMain@aol.com>
This example illustrate how to writte a custom class using a methods
table instead of a dispatcher. This class doesn't use Dynamic IDs.
*/
///Header
#include <libraries/feelin.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/utility.h>
#include <proto/feelin.h>
struct FeelinBase *FeelinBase;
#define GfxBase FeelinBase -> Graphics
#define UtilityBase FeelinBase -> Utility
/*
Using static IDs is not a good idea, but this is just a demo and I'm
lazy ;-)
*/
#define FM_Lines_Update (FCCM_BASE + 0)
#define FA_Lines_Cycle (FCCA_BASE + 0)
#define FA_Lines_Trail (FCCA_BASE + 1)
#define FA_Lines_Micro (FCCA_BASE + 2)
struct LocalObjectData
{
FAreaData *AreaData;
struct FeelinSignalHandler SignalHandler;
WORD x[2],y[2];
WORD xd[2],yd[2];
APTR ox[2],oy[2];
ULONG j;
ULONG Pen; // FV_Pen_Xxx
UBYTE Cycle;
UBYTE CycleDone;
BYTE CycleWay;
UBYTE Line; // Line to draw (or beeing drawn)
BYTE k;
UBYTE Trail;
APTR TrailData;
};
long rand(void);
#define MyLine F_NewObj(Class -> Name,TAG_DONE)
//+
///ModifyTrail
APTR ModifyTrail(struct FeelinClass *Class,FObject Obj,UBYTE Trail)
{
struct LocalObjectData *LOD = F_LOD(Class,Obj);
LOD -> Trail = 0;
if (LOD -> TrailData)
{
LOD -> ox[0] = 0; LOD -> ox[1] = 0; // Reset coordinates
LOD -> oy[0] = 0; LOD -> oy[1] = 0; // Reset coordinates
F_Dispose(LOD -> TrailData);
}
if (LOD -> TrailData = F_New(sizeof (WORD) * 4 * Trail))
{
LOD -> ox[0] = LOD -> TrailData;
LOD -> ox[1] = (APTR)((ULONG)(LOD -> ox[0]) + sizeof (WORD) * Trail);
LOD -> oy[0] = (APTR)((ULONG)(LOD -> ox[1]) + sizeof (WORD) * Trail);
LOD -> oy[1] = (APTR)((ULONG)(LOD -> oy[0]) + sizeof (WORD) * Trail);
}
LOD -> Trail = Trail;
return LOD -> TrailData;
}
//+
/// mNew
F_METHOD(APTR,mNew)
{
struct LocalObjectData *LOD = F_LOD(Class,Obj);
LOD -> AreaData = (FAreaData *) F_Get(Obj,FA_AreaData);
LOD -> Cycle = 1;
LOD -> Trail = 8;
LOD -> SignalHandler.Object = Obj;
LOD -> SignalHandler.Method = FM_Lines_Update;
LOD -> SignalHandler.Flags = FF_SignalHandler_Timer;
LOD -> SignalHandler.fsh_Secs = 0;
LOD -> SignalHandler.fsh_Micros = 10000;
if (F_SuperDo(Class,Obj,Method,
FA_ChainToCycle, FALSE,
FA_Back, FI_Dark,
FA_Frame, "FP_Gauge_Frame",
FA_Lines_Cycle, 8,
FA_Lines_Trail, 16,
TAG_MORE, Msg))
{
if (!LOD -> TrailData) ModifyTrail(Class,Obj,LOD -> Trail);
if (LOD -> TrailData)
{
return Obj;
}
}
return NULL;
}
//+
///mDispose
F_METHOD(void,mDispose)
{
struct LocalObjectData *LOD = F_LOD(Class,Obj);
if (LOD -> TrailData)
{
F_Dispose(LOD -> TrailData); LOD -> TrailData = NULL;
}
F_SUPERDO();
}
//+
///mSet
F_METHOD(void,mSet)
{
struct LocalObjectData *LOD = F_LOD(Class,Obj);
struct TagItem *Tags = Msg,
*item;
while (item = NextTagItem(&Tags))
switch (item -> ti_Tag)
{
case FA_Lines_Cycle:
{
LOD -> Cycle = item -> ti_Data;
LOD -> Pen = (LOD -> Cycle) ? FV_Pen_Shine : FV_Pen_Highlight;
}
break;
case FA_Lines_Trail:
{
if (FF_Area_CanDraw & _flags)
{
F_Do(Obj,FM_Hide);
ModifyTrail(Class,Obj,item -> ti_Data);
F_Do(Obj,FM_Show);
F_Draw(Obj,FF_Draw_Object);
}
else
{
ModifyTrail(Class,Obj,item -> ti_Data);
}
}
break;
case FA_Lines_Micro:
{
if (FF_Area_CanDraw & _flags)
{
F_Do(_app,FM_Application_RemSignalHandler,&LOD -> SignalHandler);
LOD -> SignalHandler.fsh_Micros = item -> ti_Data;
F_Do(_app,FM_Application_AddSignalHandler,&LOD -> SignalHandler);
}
else
{
LOD -> SignalHandler.fsh_Micros = item -> ti_Data;
}
}
break;
}
F_SUPERDO();
}
//+
/// mShow
F_METHOD(LONG,mShow)
{
struct LocalObjectData *LOD = F_LOD(Class,Obj);
/*
It's better to add signal handlers in the FM_Show method because the
object may be hidden at any time and even if it won't be able to be
drawn it's a waste of time (CPU time) to leave it active.
*/
if (F_SUPERDO())
{
F_Do(_app,FM_Application_AddSignalHandler,&LOD -> SignalHandler);
return TRUE;
}
return FALSE;
}
//+
/// mHide
F_METHOD(void,mHide)
{
struct LocalObjectData *LOD = F_LOD(Class,Obj);
if (FF_Area_CanShow & _flags)
{
F_Do(_app,FM_Application_RemSignalHandler,&LOD -> SignalHandler);
}
F_SUPERDO();
}
//+
/// mAskMinMax
/*
AskMinMax method will be called before the window is opened and before
layout takes place. We need to tell Feelin the minimum and maximum size of
our object. Note that we indeed need to *add* these values, not just set
them !
*/
F_METHOD(ULONG,mAskMinMax)
{
struct LocalObjectData *LOD = F_LOD(Class,Obj);
_minw += 30;
_minh += 30;
/*
Now call our superclass. FC_Area will handle everything, taking care of
FA_FixedXxx, FA_MinXxx and FA_MaxXxx.
*/
return F_SUPERDO();
}
//+
/// mDraw
/*
Draw method is called whenever Feelin feels (obviously ;-)) we should
render our object. This usually happens after layout is finished. Note: You
may only render within the rectangle _mx(Obj), _my(Obj), _mx2(Obj),
_my2(Obj).
*/
F_METHODM(void,mDraw,FS_Draw)
{
struct LocalObjectData *LOD = F_LOD(Class,Obj);
struct RastPort *rp = _rp;
register short i;
WORD *ox;
WORD *oy;
/*
let our superclass draw itself first, Area class would e.g. draw the frame
and clear the whole region. What it does exactly depends on flags.
*/
if (FF_Draw_Object & Msg -> Flags)
{
/* Reset values */
for (i = 0 ; i < 2 ; i++)
{
LOD -> x[i] = _mx + (rand() % _mw); if (LOD -> x[i] < _mx) LOD -> x[i] = _mx; else if (LOD -> x[i] > _mx2) LOD -> x[i] = _mx2;
LOD -> y[i] = _my + (rand() % _mh); if (LOD -> y[i] < _my) LOD -> y[i] = _my; else if (LOD -> y[i] > _my2) LOD -> y[i] = _my2;
LOD -> xd[i] = rand() % 10 + 1;
LOD -> yd[i] = rand() % 10 + 1;
}
LOD -> Pen = (LOD -> Cycle) ? FV_Pen_Shine : FV_Pen_Highlight;
LOD -> j = 0;
LOD -> CycleWay = 1;
LOD -> CycleDone = 0;
LOD -> Line = 0;
F_SUPERDO();
}
if (!LOD -> TrailData) return;
if (LOD -> j >= LOD -> Trail - 1)
{
i = (LOD -> Line >= LOD -> Trail - 1) ? 0 : LOD -> Line + 1;
_FPen(FV_Pen_Dark);
ox = LOD -> ox[0]; oy = LOD -> oy[0]; _Move(ox[i],oy[i]);
ox = LOD -> ox[1]; oy = LOD -> oy[1]; _Draw(ox[i],oy[i]);
}
_FPen(LOD -> Pen);
_Move(LOD -> x[0],LOD -> y[0]);
_Draw(LOD -> x[1],LOD -> y[1]);
if (LOD -> Cycle && ++LOD -> CycleDone >= LOD -> Cycle)
{
LOD -> CycleDone = 0;
if (LOD -> CycleWay > 0)
{
if (LOD -> Pen + 1 >= FV_Pen_Dark) LOD -> CycleWay = -1;
}
else
{
if (LOD -> Pen - 1 <= FV_Pen_Shine) LOD -> CycleWay = 1;
}
LOD -> Pen += LOD -> CycleWay;
}
for (i = 0 ; i < 2 ; i++)
{
ox = LOD -> ox[i]; ox[LOD -> Line] = LOD -> x[i];
oy = LOD -> oy[i]; oy[LOD -> Line] = LOD -> y[i];
LOD -> x[i] += LOD -> xd[i];
LOD -> y[i] += LOD -> yd[i];
if (LOD -> x[i] < _mx)
{
LOD -> xd[i] = -LOD -> xd[i]; LOD -> x[i] = _mx;
}
else if (LOD -> x[i] > _mx2)
{
LOD -> xd[i] = -LOD -> xd[i]; LOD -> x[i] = _mx2;
}
if (LOD -> y[i] < _my)
{
LOD -> yd[i] = -LOD -> yd[i]; LOD -> y[i] = _my;
}
else if (LOD -> y[i] > _my2)
{
LOD -> yd[i] = -LOD -> yd[i]; LOD -> y[i] = _my2;
}
/* Twisting coordinates */
if (((rand() >> 5) & 127) < 2)
{
if (LOD -> xd[i] < 1) LOD -> k = TRUE;
LOD -> xd[i] = (rand() >> 5) & 7;
if (LOD -> k) LOD -> xd[i] = -LOD -> xd[i];
LOD -> k = FALSE;
}
if (((rand() >> 5) & 255) < 50)
{
if (LOD -> yd[i] < 1) LOD -> k = TRUE;
LOD -> yd[i] = (rand() >> 5) & 7;
if (LOD -> k) LOD -> yd[i] = -LOD -> yd[i];
LOD -> k = FALSE;
}
}
if (++LOD -> Line >= LOD -> Trail) LOD -> Line = 0;
LOD -> j++;
}
//+
///mUpdate
F_METHOD(LONG,mUpdate)
{
F_Draw(Obj,FF_Draw_Update);
return TRUE; // If we return FALSE the timer event won't be requested again
}
//+
///Main
void main()
{
APTR app,win,
grp,gad_ccl,gad_trl,gad_spd;
struct FeelinClass *Class;
static struct FeelinMethodEntry Handlers[] =
{
(FMethod) mNew, NULL, FM_New,
(FMethod) mDispose, NULL, FM_Dispose,
(FMethod) mSet, NULL, FM_Set,
(FMethod) mShow, NULL, FM_Show,
(FMethod) mHide, NULL, FM_Hide,
(FMethod) mAskMinMax, NULL, FM_AskMinMax,
(FMethod) mDraw, NULL, FM_Draw,
(FMethod) mUpdate, NULL, FM_Lines_Update,
NULL
};
if (FeelinBase = (APTR) OpenLibrary("feelin.library",FV_VERSION))
{
/*
Create the new custom class with a call to F_CreateClassA().
This function returns a struct FeelinClass. You must use cc -> Name to
create instance of your custom class. This Name is unique and made by
F_CreateClassA().
*/
if (Class = F_CreateClass(FA_Class_Super, FC_Area,
FA_Class_LODSize, sizeof (struct LocalObjectData),
FA_Class_MethodsTable, Handlers,
TAG_DONE))
{
app = AppObject,
FA_Application_Title, "demo_Lines",
FA_Application_Version, "$VER: demo_Lines 1.0 (2003/02/10)",
FA_Application_Copyright, "© 2000-2003 Olivier LAVIALE",
FA_Application_Author, "Olivier LAVIALE <HaploLaMain@aol.com>",
FA_Application_Description, "Tutorial on Client.AddSignalHandler()",
FA_Application_Base, "demo_Lines",
Child, win = WindowObject,
FA_ID, MAKE_ID('M','A','I','N'),
FA_Window_Title, "Feelin : Lines",
FA_Window_Open, TRUE,
Child, grp = Page,
Child, VGroup, FA_Group_Title, "One",
Child, MyLine,
Child, HGroup,
FA_Frame, "FP_Group_Frame",
FA_Frame_Title, "Controls",
FA_SetMax, FV_SetMaxH,
FA_ContextHelp, "Settings made on this page will be reflected\nto all FC_Lines objects",
FA_Group_Columns, 2,
Child, TextObject, FA_Text, "Cycle :", FA_SetMax,TRUE, DontChain, End,
Child, gad_ccl = SliderA, TRUE,0,200,8,
FA_ID, MAKE_ID('C','Y','C','L'),
FA_ContextHelp, "Adjust the number of lines to draw\nbefore a color cyling.\n\nSetting this to 0 disable cycling.",
End,
Child, TextObject, FA_Text, "Trail :", FA_SetMax,TRUE, DontChain, End,
Child, gad_trl = SliderA, TRUE,8,100,16,
FA_ID, MAKE_ID('T','R','A','Y'),
FA_ContextHelp, "Adjust the number of trailing lines.",
End,
Child, TextObject, FA_Text, "Micros :", FA_SetMax,TRUE, DontChain, End,
Child, gad_spd = SliderA, TRUE,5000,100000,10000,
"FA_Numeric_Step", 1000,
FA_ID, MAKE_ID('S','P','E','D'),
FA_ContextHelp, "Adjust the number of micro seconds\nto wait between each drawing.",
End,
End,
End,
Child, VGroup, FA_Group_Title, "Four", FA_Group_Rows,2,
Child, MyLine, Child, MyLine,
Child, MyLine, Child, MyLine,
End,
Child, VGroup, FA_Group_Title, "More", FA_Group_Rows,4,
Child, MyLine, Child, MyLine, Child, MyLine, Child, MyLine,
Child, MyLine, Child, MyLine, Child, MyLine, Child, MyLine,
Child, MyLine, Child, MyLine, Child, MyLine, Child, MyLine,
Child, MyLine, Child, MyLine, Child, MyLine, Child, MyLine,
End,
End,
End,
End;
if (app)
{
F_Do(win,FM_Notify,FA_Window_CloseRequest,TRUE,app,FM_Application_Shutdown,0);
F_Do(gad_ccl,FM_Notify,"FA_Numeric_Value",FV_Notify_Always,grp,FM_Set,4,FA_Lines_Cycle,FV_Notify_Value,FA_Group_Forward,TRUE);
F_Do(gad_trl,FM_Notify,"FA_Numeric_Value",FV_Notify_Always,grp,FM_Set,4,FA_Lines_Trail,FV_Notify_Value,FA_Group_Forward,TRUE);
F_Do(gad_spd,FM_Notify,"FA_Numeric_Value",FV_Notify_Always,grp,FM_Set,4,FA_Lines_Micro,FV_Notify_Value,FA_Group_Forward,TRUE);
F_Do(app,FM_Application_Run);
F_DisposeObj(app);
}
F_DeleteClass(Class);
}
else
{
Printf("Unable to create custom class.\n");
}
CloseLibrary(FeelinBase);
}
else
{
Printf("Unable to open feelin.library v%ld.\n",FV_VERSION);
}
}
//+